package com.example.config.batchjob;

import com.example.entity.StudentItem;
import com.example.entity.StudentTotalScore;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.LineMapper;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;


import javax.sql.DataSource;


@Slf4j
@Configuration
@EnableBatchProcessing
public class BatchConfig {

    @Value("${batch.input.file.path}")
    private String inputFile;


    @Bean
    public Job job(JobRepository jobRepository, PlatformTransactionManager transactionManager, DataSource dataSource) {
        return new JobBuilder("job4", jobRepository)
                .incrementer(new RunIdIncrementer()) // 重复执行job
                .start(step(jobRepository, transactionManager, dataSource))
                .listener(new MyJobExecutionListener())
                .build();
    }

    private Step step(JobRepository jobRepository, PlatformTransactionManager transactionManager, DataSource dataSource) {
        return new StepBuilder("step", jobRepository)
                .<StudentItem, StudentTotalScore>chunk(100, transactionManager)
                .reader(studentItemReader())
                .processor(studentItemProcessor())
//                .writer(writer())
                .writer(totalScoreItemWriter(dataSource))
//                .allowStartIfComplete(true) // 重复执行step
                .build();
    }

    @Bean
    public FlatFileItemReader<StudentItem> studentItemReader() {
        FlatFileItemReader<StudentItem> reader = new FlatFileItemReader<>();
        reader.setResource(new ClassPathResource(inputFile)); // 从类路径读取文件
        reader.setLineMapper(studentLineMapper());
        return reader;
    }

    private LineMapper<StudentItem> studentLineMapper() {
        DefaultLineMapper<StudentItem> lineMapper = new DefaultLineMapper<>();
        DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
        lineTokenizer.setNames(new String[]{"id", "chinese", "math", "english"});
        lineTokenizer.setIncludedFields(new int[]{0, 1, 2, 3});

        BeanWrapperFieldSetMapper<StudentItem> fieldSetMapper =
                new BeanWrapperFieldSetMapper<>();
        fieldSetMapper.setTargetType(StudentItem.class);

        lineMapper.setLineTokenizer(lineTokenizer);
        lineMapper.setFieldSetMapper(fieldSetMapper);
        return lineMapper;
    }

    // === 3. 配置 ItemProcessor（计算总分）===
    @Bean
    public ItemProcessor<StudentItem, StudentTotalScore> studentItemProcessor() {
        return student -> {
            log.info("studentItemProcessor {}", student.toString());
            int total = student.getChinese() + student.getMath() + student.getEnglish();
            return new StudentTotalScore(student.getId(), total);
        };
    }

    private ItemWriter<StudentTotalScore> writer() {
        return items -> items.forEach(item -> {
            System.out.println("zjy---" + item);
        });
    }


    // === 4. 配置 ItemWriter（写入数据库）===
    @Bean
    public JdbcBatchItemWriter<StudentTotalScore> totalScoreItemWriter(
            DataSource dataSource) {
        return new JdbcBatchItemWriterBuilder<StudentTotalScore>()
                .itemSqlParameterSourceProvider(
                        new BeanPropertyItemSqlParameterSourceProvider<>())
                .sql("INSERT INTO student_total_score (id, total_score) " +
                        "VALUES (:id, :totalScore)")
                .dataSource(dataSource)
                .build();
    }


    // === 5. 数据库初始化（可选）===
    @Bean
    public JdbcTemplate initDatabase(DataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS student_total_score ( " +
                "id VARCHAR(255) PRIMARY KEY, " +
                "total_score INT NOT NULL)");
        log.info("Database initialized successfully");
        return jdbcTemplate;
    }

}